package com.baor.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baor.dao.*;
import com.baor.domain.*;
import com.baor.service.CommonService;
import com.baor.utils.AjaxResult;
import com.baor.utils.BaiduUtil;
import com.baor.utils.UploadUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.baor.utils.DateUtil.now;


@Service
public class CommonServiceImpl implements CommonService {

    private final Integer min = 100000000;

    private final Integer max = 888888888;

    @Autowired
    private UploadUtil uploadUtil;

    @Autowired
    private CarDao carDao;

    @Autowired
    private FinanceDao financeDao;

    @Autowired
    private StopDao stopDao;

    @Autowired
    private ParkingDao parkingDao;

    @Autowired
    private CooperateDao cooperateDao;

    @Override
    public AjaxResult<?> upload(MultipartFile[] files) {
        List<String> uploads = uploadUtil.uploads(files, "src/main/resources/static/img/");
        return AjaxResult.success(uploads);
    }

    @Override
    public AjaxResult<List<String>> getImage(Map<String,Object> map) {
        String filePath = map.get("url").toString();
        //baidu
        String result = BaiduUtil.accurateBasic(filePath);
        System.out.println(result);
        if ( result == null )
            return AjaxResult.error("未识别到信息",null);
        Gson gson = new Gson();
        Map<String,Object> json = gson.fromJson(result, new TypeToken<Map<String, Object>>() {
        }.getType());
        System.out.println(json);//{"words_result":[{"words":"pepsi"}],"words_result_num":1,"log_id":1787087981996251056}
        List<Map<String,Object>> wordsResult = (List<Map<String,Object>>)json.get("words_result");
        List<String> list = new ArrayList<>();
        for ( Map<String,Object> mp :wordsResult ){
            list.add(mp.get("words").toString());
        }
        System.out.println(list);//车牌集
        return AjaxResult.success(list);
    }

    @Override
    public AjaxResult<?> check(List<String> getImage,String parkingId) {

//        String str = "冀A.S2412";
        for ( String str :getImage )
        {
            List<CarVo> carVos = carDao.selectList(new LambdaQueryWrapper<CarVo>().eq(CarVo::getCarLicense, str).eq(CarVo::getCarParking,parkingId));
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            Boolean flag = true;//默认收费
            // ------------- 是否免费期间
            if ( carVos.size() > 0 && "包月车" .equals(carVos.get(0).getCarEffective()) ){
                String carCreatetime = carVos.get(0).getCarCreatetime();
                LocalDateTime dateTime = LocalDateTime.parse(carCreatetime, formatter);//包月车创建时间
                // 获取现在的日期时间
                LocalDateTime now = LocalDateTime.now();//现在
                // 判断是否在现在30天之前
                LocalDateTime thirtyDaysAgo = now.minusDays(30);
                if( dateTime.isBefore(thirtyDaysAgo) ) {//
                    System.out.println(carCreatetime + " 在现在30天之前");// -> 收费
                    flag = false;
                }
            }
            List<StopVo> stopVos = stopDao.selectList(new LambdaQueryWrapper<StopVo>().eq(StopVo::getStopLicense, str).eq(StopVo::getStopParking, parkingId).orderByDesc(StopVo::getStopEntrytime));
            if ( stopVos.size() >0 && ("".equals(stopVos.get(0).getStopOuttime()) || stopVos.get(0).getStopOuttime() == null) ) {//停过车 -> 离开\再次进来
                //离开
                StopVo stopVo = stopVos.get(0);
                stopVo.setStopOuttime(now());
                ParkingVo parkingVo = parkingDao.selectById(stopVo.getStopParking());
                LocalDateTime outTime = LocalDateTime.parse(stopVo.getStopOuttime(), formatter);
                LocalDateTime entryTime = LocalDateTime.parse(stopVo.getStopEntrytime(), formatter);
                long milliseconds1 = outTime.toInstant(ZoneOffset.UTC).toEpochMilli();
                long milliseconds2 = entryTime.toInstant(ZoneOffset.UTC).toEpochMilli();
                long diffMilliseconds = Math.abs(milliseconds1 - milliseconds2);
                long diffMinutes = diffMilliseconds / 60000;//分钟差
                BigDecimal bigDecimal = new BigDecimal(diffMinutes);
                System.out.println("if ( flag ) -> :" + flag );
                if ( parkingVo.getParkingFree().compareTo(bigDecimal) < 0 ){//收费
                    BigDecimal parkingUnit = parkingVo.getParkingUnit();
                    BigDecimal parkingUnitMoney = parkingVo.getParkingUnitMoney();
                    BigDecimal subtract = parkingUnit.subtract(bigDecimal);
                    BigDecimal multiply = subtract.multiply(parkingUnitMoney);
                    if ( multiply.compareTo(parkingVo.getParkingMax()) > 0  ){
                        System.out.println("mu");
                        multiply = parkingVo.getParkingMax();
                    }
                    FinanceVo financeVo = new FinanceVo();
                    financeVo.setFinanceCreatetime(now());
                    financeVo.setFinanceLicense(str);
                    financeVo.setFinanceMoney(multiply);
                    financeVo.setFinanceName("GTIN" + (Math.ceil(Math.random()*(max-min)+min)));
                    financeVo.setFinanceNotes("无");
                    financeVo.setFinancePays("微信");
                    financeDao.insert(financeVo);
                    stopVo.setStopMoney(multiply);
                } else {//不收费
                    FinanceVo financeVo = new FinanceVo();
                    financeVo.setFinanceCreatetime(now());
                    financeVo.setFinanceLicense(str);
                    financeVo.setFinanceMoney(BigDecimal.ZERO);
                    financeVo.setFinanceName("GTIN" + (Math.ceil(Math.random()*(max-min)+min)));
                    financeVo.setFinanceNotes("无");
                    financeVo.setFinancePays("未收取费用");
                    financeDao.insert(financeVo);
                    stopVo.setStopMoney(BigDecimal.ZERO);
                    if ( carVos.size() > 0 )
                        stopVo.setStopCooperate(carVos.get(0).getCarCooperate());//合作公司?
                }
                stopVo.setStopOuttime(now());
                stopDao.updateById(stopVo);
            } else {
                //再次进入//初次进入
                StopVo stopVo = new StopVo();
                stopVo.setStopParking(parkingId);
                stopVo.setStopEntrytime(now());
                stopVo.setStopLicense(str);
                stopVo.setStopStatus("临时车");
                if ( carVos.size() > 0  ){
                    stopVo.setStopStatus(carVos.get(0).getCarEffective());
                }
                stopDao.insert(stopVo);
            }
        }
        return AjaxResult.success();
    }
    //入场
    @Override
    public AjaxResult<?> entry(Map<String, Object> map) {
        AjaxResult<String> ajaxResult = getWords(map);//url -> words
        if ( ajaxResult.getCode().equals("500") )
           return AjaxResult.error("未识别到信息",null);
        String license = ajaxResult.getData();
        String parkingId = map.get("parkingId").toString();
        StopVo stopVo = new StopVo();
        stopVo.setStopEntrytime(now());
        stopVo.setStopLicense(license);
        stopVo.setStopParking(parkingId);
        stopVo.setStopStatus("临时车");
        stopVo.setStopCooperate("0");//错误 此处 改为 null
        List<StopVo> stopVos = stopDao.selectList(new LambdaQueryWrapper<StopVo>().eq(StopVo::getStopParking, parkingId).isNull(StopVo::getStopOuttime));
        if ( stopVos.size() > 0 )
            return AjaxResult.error("请先离场",null);
        //是否合作公司
        List<CarVo> carVos = carDao.selectList(new LambdaQueryWrapper<CarVo>().eq(CarVo::getCarLicense, license).eq(CarVo::getCarParking, parkingId));
        if ( carVos.size() > 0 ){
            stopVo.setStopCooperate(carVos.get(0).getCarCooperate());
            stopVo.setStopStatus(carVos.get(0).getCarEffective());
        }
        int insert = stopDao.insert(stopVo);
        return insert > 0 ? AjaxResult.success(stopVo.getStopId()) : AjaxResult.error("插入失败");
    }

    @Override
    public AjaxResult<?> out(Map<String, Object> map) {
        AjaxResult<String> ajaxResult = getWords(map);//url -> words
        if ( ajaxResult.getCode().equals("500") )
            return AjaxResult.error("未识别到信息",null);
        String license = ajaxResult.getData();
        String parkingId = map.get("parkingId").toString();
        List<StopVo> stopVos = stopDao.selectList(new LambdaQueryWrapper<StopVo>().eq(StopVo::getStopLicense, license).eq(StopVo::getStopParking, parkingId).isNull(StopVo::getStopOuttime));
        if ( stopVos.size() == 0 )
            return AjaxResult.error("请先入场（一般不会有这个错误）",null);
        ParkingVo parkingVo = parkingDao.selectOne(new LambdaQueryWrapper<ParkingVo>().eq(ParkingVo::getParkingId, parkingId));
        StopVo stopVo = stopVos.get(0);
        stopVo.setStopOuttime(now());
        CarVo carVo = carDao.selectOne(new LambdaQueryWrapper<CarVo>().eq(CarVo::getCarLicense, license));
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        boolean flag = true;
        boolean flag2 = true;//默认true -> 收费
        i:if ( carVo != null ){
            if ( "永久免费车".equals(carVo.getCarEffective()) ){
                stopVo.setStopMoney(BigDecimal.ZERO);
                flag = false;
                break i;
            }
            String carCreatetime = carVo.getCarCreatetime();
            LocalDateTime dateTime = LocalDateTime.parse(carCreatetime, formatter);//包月车创建时间
            // 获取现在的日期时间
            LocalDateTime now = LocalDateTime.now();//现在
            // 判断是否在现在30天之前
            long daysDifference = ChronoUnit.DAYS.between(dateTime, now);
            if (daysDifference >= 0 && daysDifference < 30) {
                System.out.println("该日期在最近30天之内");
                stopVo.setStopMoney(BigDecimal.ZERO);
                flag2 = false;
            }
        }
         if ( flag && flag2 ){//
            LocalDateTime outTime = LocalDateTime.parse(stopVo.getStopOuttime(), formatter);
            LocalDateTime entryTime = LocalDateTime.parse(stopVo.getStopEntrytime(), formatter);
            long milliseconds1 = outTime.toInstant(ZoneOffset.UTC).toEpochMilli();
            long milliseconds2 = entryTime.toInstant(ZoneOffset.UTC).toEpochMilli();
            long diffMilliseconds = Math.abs(milliseconds1 - milliseconds2);
            long diffMinutes = diffMilliseconds / 60000;//分钟差
             System.out.println("时间差" + diffMinutes);
            BigDecimal bigDecimal = new BigDecimal(diffMinutes);
             BigDecimal parkingFree = parkingVo.getParkingFree();
            BigDecimal parkingUnit = parkingVo.getParkingUnit();
            BigDecimal parkingUnitMoney = parkingVo.getParkingUnitMoney();
            BigDecimal subtract = bigDecimal.subtract(parkingFree);
            BigDecimal multiply = subtract.multiply(parkingUnitMoney);
             BigDecimal divide = multiply.divide(parkingUnit);
             if ( divide.compareTo(BigDecimal.ZERO) < 0 )
                 divide = BigDecimal.ZERO;
             System.out.println(bigDecimal);
             System.out.println(parkingUnit);
             System.out.println(parkingUnitMoney);
             System.out.println(subtract);
             System.out.println(multiply);
             System.out.println(divide);
             System.out.println(parkingVo.getParkingMax());
            if ( multiply.compareTo(parkingVo.getParkingMax()) > 0  ){
                System.out.println("mu");
                divide = parkingVo.getParkingMax();
            }
            FinanceVo financeVo = new FinanceVo();
            financeVo.setFinanceCreatetime(now());
            financeVo.setFinanceLicense(license);
            financeVo.setFinanceMoney(divide);
            financeVo.setFinanceName("GTIN" + (Math.ceil(Math.random()*(max-min)+min)));
            financeVo.setFinanceNotes("无");
            financeVo.setFinancePays("微信");
            financeDao.insert(financeVo);
            stopVo.setStopMoney(divide);
        }
         stopDao.updateById(stopVo);
        return AjaxResult.success();
    }

    private AjaxResult<String> getWords(Map<String,Object> map){
        String filePath = map.get("url").toString();
        //baidu
        String result = BaiduUtil.accurateBasic(filePath);
//        System.out.println(result);
        if ( result == null )
            return AjaxResult.error();
        Gson gson = new Gson();
        Map<String,Object> json = gson.fromJson(result, new TypeToken<Map<String, Object>>() {
        }.getType());
//        System.out.println(json);//{"words_result":[{"words":"pepsi"}],"words_result_num":1,"log_id":1787087981996251056}
        List<Map<String,Object>> wordsResult = (List<Map<String,Object>>)json.get("words_result");
        if( wordsResult.size() ==0 )
            return AjaxResult.error();
        System.out.println(wordsResult);
        String words = wordsResult.stream().filter(x -> x.get("words").toString()
                        .matches("([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]{1})))|([A-HJ-Z]{1}[A-D0-9]{1}[0-9]{3}警)))|([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})|([VKHBSLJNGCE]{1}[A-DJ-PR-TVY]{1}[0-9]{5})"))
                .findFirst().orElse(null).get("words").toString();
        return AjaxResult.success(words);
    }

}
